﻿// <copyright file="CurveDataView.cs" company="Oleg V. Polikarpotchkin">
// Copyright © 2008-2009 Oleg V. Polikarpotchkin. All Right Reserved
// </copyright>
// <author>Oleg V. Polikarpotchkin</author>
// <email>ov-p@yandex.ru</email>
// <date>2009-01-19</date>
// <summary>OpenWPFChart library. CurveDataView is the abstract base class of all Curve Data View classes.</summary>
// <revision>$Id$</revision>

using System;
using System.Windows.Media;

namespace OpenWPFChart.Parts
{
	/// <summary>
	/// Abstract base class of all OpenWPFChart Curve Data View classes.
	/// </summary>
	/// <remarks>
	/// <see cref="CurveDataView"/> is the <see cref="ItemDataView"/> with a 
	/// <see cref="System.Windows.Media.Pen"/> to draw the Curve line and a 
	/// <see cref="System.Windows.Media.Brush"/> to fill the area between the Curve and the
	/// Horizontal axis.
	/// </remarks>
	public abstract class CurveDataView : ItemDataView
	{
		/// <summary>
		/// Initializes a new instance of the <see cref="CurveDataView"/> class.
		/// </summary>
		public CurveDataView()
		{
			pen = new Pen(Brushes.Black, 1);
			pen.Changed += PenChanged;
		}

		#region Pen
		Pen pen;
		/// <summary>
		/// Gets or sets the <see cref="Pen"/>  property.
		/// </summary>
		/// <value>Any <see cref="System.Windows.Media.Pen"/> or <c>null</c>.</value>
		/// <remarks>
		/// This <see cref="System.Windows.Media.Pen"/> is used to draw the Curve line. 
		/// If the <c>Pen</c> is <c>null</c> the Curve isn't rendered.
		/// </remarks>
		public Pen Pen
		{
			get { return pen; }
			set
			{
				if (pen != value)
				{
					if (pen != null && !pen.IsFrozen)
						pen.Changed -= PenChanged;
					pen = value;
					if (pen != null && !pen.IsFrozen)
						pen.Changed += PenChanged;
					NotifyPropertyChanged("Pen");
				}
			}
		}

		/// <summary>
		/// Pen changed.
		/// </summary>
		/// <param name="sender">The sender.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		void PenChanged(object sender, EventArgs e)
		{
			NotifyPropertyChanged("Pen");
		}
		#endregion Pen

		#region FillArea
		bool fillArea;
		/// <summary>
		/// Gets or sets the <see cref="FillArea"/> property.
		/// </summary>
		/// <value><c>true</c> if the Curve area should be filled.</value>
		/// <remarks>
		/// <c>true</c> indicates that the area between the Curve line and the Horizontal axis should
		/// be filled.
		/// </remarks>
		public bool FillArea
		{
			get { return fillArea; }
			set
			{
				if (fillArea != value)
				{
					fillArea = value;
					NotifyPropertyChanged("FillArea");
				}
			}
		}
		#endregion FillArea

		#region AreaBrush
		Brush areaBrush;
		/// <summary>
		/// Gets or sets the <see cref="AreaBrush"/> property.
		/// </summary>
		/// <value>Any <see cref="System.Windows.Media.Brush"/> or <c>null</c> (the default).</value>
		/// <remarks>
		/// This <see cref="System.Windows.Media.Brush"/> is used to fill the area between the Curve 
		/// line and the Horizontal axis. If the <c>AreaBrush</c> is <c>null</c> the area isn't filled.
		/// </remarks>
		public Brush AreaBrush
		{
			get { return areaBrush; }
			set
			{
				if (areaBrush != value)
				{
					if (areaBrush != null && !areaBrush.IsFrozen)
						areaBrush.Changed -= AreaBrushChanged;
					areaBrush = value;
					if (areaBrush != null && !areaBrush.IsFrozen)
						areaBrush.Changed += AreaBrushChanged;
					NotifyPropertyChanged("AreaBrush");
				}
			}
		}

		/// <summary>
		/// AreaBrush changed.
		/// </summary>
		/// <param name="sender">The sender.</param>
		/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
		void AreaBrushChanged(object sender, EventArgs e)
		{
			NotifyPropertyChanged("AreaBrush");
		}
		#endregion AreaBrush

		#region ICloneable Override
		/// <summary>
		/// Creates a new object that is a copy of the current instance.
		/// </summary>
		/// <returns>
		/// A new object that is a copy of this instance.
		/// </returns>
		/// <remarks>This method is designed to provide the deep cloning facility if desired.</remarks>
		protected override object CloneInternal()
		{
			CurveDataView clone = base.CloneInternal() as CurveDataView;
			// Pen.
			if (pen != null)
			{
				clone.pen = pen.Clone();
				clone.pen.Changed += clone.PenChanged;
			}
			// AreaBrush.
			if (areaBrush != null)
			{
				clone.areaBrush = areaBrush.Clone();
				clone.areaBrush.Changed += clone.AreaBrushChanged;
			}
			return clone;
		}
		#endregion ICloneable Override
	}
}
